﻿/******************************************************************************
* SunnyUI.FrameDecoder 开源TCP、串口数据解码库。
* CopyRight (C) 2022-2023 ShenYongHua(沈永华).
* QQ群：56829229 QQ：17612584 EMail：SunnyUI@qq.com
*
* Blog:   https://www.cnblogs.com/yhuse
* Gitee:  https://gitee.com/yhuse/SunnyUI.FrameDecoder
*
* SunnyUI.FrameDecoder.dll can be used for free under the MIT license.
* If you use this code, please keep this note.
* 如果您使用此代码，请保留此说明。
******************************************************************************
* 文件名称: ThrowHelper.cs
* 文件说明: 抛异常帮助类
* 当前版本: V1.0
* 创建日期: 2022-11-01
*
* 2022-11-01: V1.0.0 增加文件说明
******************************************************************************/

using System;
using System.Buffers;

namespace Sunny.FrameDecoder
{
    /// <summary>
    /// 编码异常类
    /// </summary>
    internal class FrameDecoderException : Exception
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="message">消息</param>
        public FrameDecoderException(string message) : base(message) { }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="innerException">异常</param>
        public FrameDecoderException(string message, Exception innerException) : base(message, innerException) { }
    }

    /// <summary>
    /// 抛异常帮助类
    /// </summary>
    internal static class ThrowHelper
    {
        /// <summary>
        /// 抛异常
        /// </summary>
        /// <param name="message">消息</param>
        public static void ThrowMessage(string message)
        {
            throw new FrameDecoderException(message);
        }

        private static void ThrowGreater<T>(string paramName, T value, T other)
        {
            throw new ArgumentOutOfRangeException(paramName, value, "参数: " + paramName + "超出范围，必须小于等于 " + other);
        }

        private static void ThrowGreaterEqual<T>(string paramName, T value, T other)
        {
            throw new ArgumentOutOfRangeException(paramName, value, "参数: " + paramName + "超出范围，必须小于 " + other);
        }

        private static void ThrowLess<T>(string paramName, T value, T other)
        {
            throw new ArgumentOutOfRangeException(paramName, value, "参数: " + paramName + "超出范围，必须大于等于 " + other);
        }

        private static void ThrowLessEqual<T>(string paramName, T value, T other)
        {
            throw new ArgumentOutOfRangeException(paramName, value, "参数: " + paramName + "超出范围，必须大于 " + other);
        }

        internal static void ThrowIfZero(int value, string paramName)
        {
            if (value == 0)
                throw new ArgumentOutOfRangeException(paramName, value, "参数: " + paramName + "超出范围，不能等于 0 ");
        }

        internal static void ThrowIfGreaterThan<T>(T value, T other, string paramName = null) where T : IComparable<T>
        {
            if (value.CompareTo(other) > 0)
                ThrowGreater(paramName, value, other);
        }

        internal static void ThrowIfGreaterThanOrEqual<T>(T value, T other, string paramName = null) where T : IComparable<T>
        {
            if (value.CompareTo(other) >= 0)
                ThrowGreaterEqual(paramName, value, other);
        }

        internal static void ThrowIfLessThan<T>(T value, T other, string paramName = null) where T : IComparable<T>
        {
            if (value.CompareTo(other) < 0)
                ThrowLess(paramName, value, other);
        }

        internal static void ThrowIfLessThanOrEqual<T>(T value, T other, string paramName = null) where T : IComparable<T>
        {
            if (value.CompareTo(other) <= 0)
                ThrowLessEqual(paramName, value, other);
        }

        internal static void ThrowIfNull(object argument, string paramName = null)
        {
            if (argument is null)
            {
                throw new ArgumentNullException(paramName);
            }
        }

        internal static FrameDecoderException Exception(string message = null)
        {
            return new FrameDecoderException(message);
        }

        internal static void ThrowSequenceReachedEnd()
        {
            throw Exception("序列已结束，读取器无法提供更多缓冲区");
        }

        internal static void ThrowInvalidAdvance()
        {
            throw Exception("无法前进到缓冲区末尾");
        }

        internal static void ThrowFailedEncoding(OperationStatus status)
        {
            throw Exception($"Utf8编码/解码过程失败, 状态: {status}");
        }

        internal static void ThrowInsufficientBufferUnless(int length)
        {
            throw Exception($"长度标头大小大于缓冲区大小, 长度: {length}.");
        }

        internal static void ThrowWriteInvalidMemberCount(byte memberCount)
        {
            throw Exception($"MemberCount/Tag 允许 < 250，但是写入了：{memberCount}.");
        }

        internal static void ThrowInvalidOperationException_AdvancedTooFar(int capacity)
        {
            throw new InvalidOperationException("通知内存对象写入的长度超过了内存区的长度：" + capacity);
        }

        internal static void ThrowOutOfMemoryException(uint capacity)
        {
            throw new OutOfMemoryException("超过缓冲区最大量：" + capacity);
        }
    }
}
